package com.example.elderlycare.service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.elderlycare.dao.entity.*;
import com.example.elderlycare.dao.mapper.*;
import com.example.elderlycare.service.RosterService;
import com.example.elderlycare.service.entity.QueryListResponseBody;
import com.example.elderlycare.service.entity.RosterItem;
import com.example.elderlycare.service.entity.RosterStatisticsResponseBody;
import com.example.elderlycare.service.entity.TemplateItem;
import com.example.elderlycare.utils.FormatDate;
import com.example.elderlycare.utils.excel.ExcelUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RosterServiceImpl extends ServiceImpl<RosterMapper, Roster> implements RosterService {
    @Resource
    RosterMapper rosterMapper;

    @Resource
    DepartmentMapper departmentMapper;

    @Resource
    CommonMapper commonMapper;

    @Resource
    EmployeeMapper employeeMapper;

    @Resource
    NursingHomeMapper nursingHomeMapper;

    /**
     * generateRosterRecord  生成排班记录
     *
     * @param params 参数
     * @return List<Roster>
     */
    @Override
    public List<Roster> generateRosterRecord(Map<String, Object> params) throws IOException {
        BaseRoster baseRoster = Factory.getRosterFactory(params);
        return baseRoster.generateRosterRecord(params);
    }

    /**
     * queryRosterList 根据条件筛选Roster记录
     *
     * @param params 查询参数
     * @return QueryListResponseBody<RosterItem>
     */
    @Override
    public QueryListResponseBody<RosterItem> queryRosterList(Map<String, Object> params) {
        List<Roster> rosterList = rosterMapper.queryByParams(params);
        Integer count = rosterMapper.queryRosterCount(params);
        QueryListResponseBody.QueryListResponseBodyBuilder<RosterItem> queryListResponseBodyBuilder = QueryListResponseBody.builder();
        queryListResponseBodyBuilder.total(count);
        List<RosterItem> rosterItems = new ArrayList<>();
        rosterList.forEach((item) -> {
            RosterItem.RosterItemBuilder rosterItemBuilder = RosterItem.builder();
            rosterItemBuilder.id(item.getId()).
                    time(FormatDate.getFormatDate(item.getDutyAt())).
                    type(item.getType()).
                    employeeId(item.getEmployeeId()).
                    employee(item.getEmployee() == null ? "未定义" : item.getEmployee().getName()).
                    absent(item.getAbsent() != 0 ? "是" : "否").
                    leave(item.getIsLeave() != 0 ? "是" : "否");

            Employee employee = item.getEmployee();
            Common position = commonMapper.selectById(employee.getPositionId());
            Department department = departmentMapper.selectById(employee.getDepartmentId());
            rosterItemBuilder.department(department == null ? "未定义" : department.getName()).
                    position(position == null ? "未定义" : position.getName());

            rosterItems.add(rosterItemBuilder.build());
        });

        queryListResponseBodyBuilder.items(rosterItems);

        return queryListResponseBodyBuilder.build();
    }

    @Override
    public QueryListResponseBody<RosterStatisticsResponseBody> queryRosterStatisticsList(Map<String, Object> params) {
        List<RosterCount> allList = rosterMapper.queryAll(params);
        List<RosterCount> absentList = rosterMapper.queryAbsent(params);
        List<RosterCount> leaveList = rosterMapper.queryLeave(params);

        int totalCount = allList.size();

        List<RosterStatisticsResponseBody> rosterStatisticsResponseBodyList = allList.stream().map(item -> {
            RosterStatisticsResponseBody.RosterStatisticsResponseBodyBuilder rosterStatisticsResponseBodyBuilder = RosterStatisticsResponseBody.builder();

            rosterStatisticsResponseBodyBuilder.countAll(item.getCount());

            Employee employee = employeeMapper.selectById(item.getEmployeeId());
            rosterStatisticsResponseBodyBuilder.employeeId(item.getEmployeeId()).
                    employee(employee == null ? "未定义" : employee.getName());

            Department department = departmentMapper.selectById(item.getDepartmentId());
            rosterStatisticsResponseBodyBuilder.departmentId(item.getDepartmentId()).
                    department(department == null ? "未定义" : department.getName());

            if (employee == null) {
                rosterStatisticsResponseBodyBuilder.nurseHomeId(0).
                        nurseHome("未定义").
                        positionId(0).
                        position("未定义");
            }
            if (employee != null) {
                NursingHome nursingHome = nursingHomeMapper.selectById(employee.getNurseId());
                rosterStatisticsResponseBodyBuilder.nurseHomeId(employee.getNurseId()).
                        nurseHome(nursingHome == null ? "未定义" : nursingHome.getName());

                Common position = commonMapper.selectById(employee.getPositionId());
                rosterStatisticsResponseBodyBuilder.positionId(employee.getPositionId()).
                        position(position == null ? "未定义" : position.getName());
            }

            RosterCount absent = getRosterCountFromList(item.getEmployeeId(), absentList);
            rosterStatisticsResponseBodyBuilder.countAbsent(absent == null ? 0 : absent.getCount());

            RosterCount leaved = getRosterCountFromList(item.getEmployeeId(), leaveList);
            rosterStatisticsResponseBodyBuilder.countLeave(leaved == null ? 0 : leaved.getCount());

            return rosterStatisticsResponseBodyBuilder.build();
        }).collect(Collectors.toList());

        return QueryListResponseBody.<RosterStatisticsResponseBody>builder().
                total(totalCount).
                items(rosterStatisticsResponseBodyList).
                build();
    }

    @Override
    public void getImportTemplate(HttpServletResponse response) throws IOException {
        List<TemplateItem> items = new ArrayList<>();
        Workbook wb = ExcelUtil.export(items, TemplateItem.class);
        ExcelUtil.writeToResponse(response, wb);
    }

    private static RosterCount getRosterCountFromList(Integer employeeId, List<RosterCount> countList) {
        return countList.stream().
                filter(rosterCount -> rosterCount.getEmployeeId().equals(employeeId)).
                findAny().
                orElse(null);
    }

}
